package it.unipr.ce.dsg.deus.automator;

import it.unipr.ce.dsg.deus.automator.gui.EngineParameter;
import it.unipr.ce.dsg.deus.automator.gui.GnuPlotFileElement;
import it.unipr.ce.dsg.deus.automator.gui.Node;
import it.unipr.ce.dsg.deus.automator.gui.NodeParameter;
import it.unipr.ce.dsg.deus.automator.gui.NodeResource;
import it.unipr.ce.dsg.deus.automator.gui.ProcessParameter;
import java.util.ArrayList;

/**
 * This class allows to start the simulation without opening its GUI.
 * 
 * @author Marco Picone (picone.m@gmail.com)
 */
public class DeusSimulationPanelCommandLine {

	public static ArrayList<ArrayList<Object>> simulations = new ArrayList<ArrayList<Object>>();

	private ArrayList<NodeParameter> nodeParameterList;
	private ArrayList<NodeResource> nodeResourceList;
	private ArrayList<ProcessParameter> processParameterList;
	private ArrayList<EngineParameter> engineParameterList;
	private ArrayList<GnuPlotFileElement> gnuPlotFileList;
	private ArrayList<Node> nodeList;

	/** Creates new form DeusSimulationPanel */
	public DeusSimulationPanelCommandLine() {
		initComponents();
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	// <editor-fold defaultstate="collapsed"
	// desc="Generated Code">//GEN-BEGIN:initComponents
	private void initComponents() {

		nodeParameterList = new ArrayList<NodeParameter>();
		nodeResourceList = new ArrayList<NodeResource>();
		processParameterList = new ArrayList<ProcessParameter>();
		engineParameterList = new ArrayList<EngineParameter>();
		gnuPlotFileList = new ArrayList<GnuPlotFileElement>();

	}

	public String createSimulationXML(String simulationTitle, int i) {

		String xmlString = "";

		// <simulation simulationNumberSeed="6" simulationName="speedSimulation">
		xmlString = xmlString + "<simulation simulationNumberSeed=\""
				+ this.engineParameterList.size() + "\" simulationName=\""
				+ simulationTitle + "\">\n";

		// Create the ArrayList for the nodes to be described in the XML file
		nodeList = new ArrayList<Node>();

		// Analyze the NodeParameters
		for (int index = 0; index < this.nodeParameterList.size(); index++) {

			NodeParameter nodeParameter = this.nodeParameterList.get(index);
			Node appNode = new Node(nodeParameter.getNodeId());

			int position = this.nodeList.indexOf(appNode);

			// if node with same ID not in list
			if (position == -1) {
				appNode.getNodeParameterList().add(nodeParameter);
				this.nodeList.add(appNode);
			} else {
				this.nodeList.get(position).getNodeParameterList()
						.add(nodeParameter);
			}
		}

		// Analyze the NodeResources
		for (int index = 0; index < this.nodeResourceList.size(); index++) {

			NodeResource nodeResource = this.nodeResourceList.get(index);
			Node appNode = new Node(nodeResource.getNodeId());

			int position = this.nodeList.indexOf(appNode);

			// if node with same ID not in list
			if (position == -1) {
				appNode.getNodeResourceList().add(nodeResource);
				this.nodeList.add(appNode);
			} else {
				this.nodeList.get(position).getNodeResourceList()
						.add(nodeResource);
			}
		}

		ArrayList<Object> app = new ArrayList<Object>();

		// Print obtained nodes
		for (int index = 0; index < this.nodeList.size(); index++) {
			app.add(this.nodeList.get(index));
			xmlString = xmlString + this.nodeList.get(index).getXMLTag();
		}

		/**
		 * Writing of processes
		 * 
		 * <process id="serverPoisson1"> <paramName name="meanArrival">
		 * <initialValue>10</initialValue> <finalValue>60</finalValue>
		 * <stepValue>10</stepValue> </paramName> </process>
		 */
		for (int index = 0; index < this.processParameterList.size(); index++) {
			app.add(this.processParameterList.get(index));
			ProcessParameter processParameter = this.processParameterList
					.get(index);
			xmlString = xmlString + "\n" + "<process id=\""
					+ processParameter.getProcessId() + "\">";
			xmlString = xmlString + "\n\t" + "<paramName name=\""
					+ processParameter.getParamName() + "\">";
			xmlString = xmlString + "\n\t\t" + "<initialValue>"
					+ processParameter.getInitialValue() + "</initialValue>";
			xmlString = xmlString + "\n\t\t" + "<finalValue>"
					+ processParameter.getFinalValue() + "</finalValue>";
			xmlString = xmlString + "\n\t\t" + "<stepValue>"
					+ processParameter.getStepValue() + "</stepValue>";
			xmlString = xmlString + "\n\t" + "</paramName>" + "\t";
			xmlString = xmlString + "\n" + "</process>" + "\n\t";
		}

		/**
		 * Writing of Engine values
		 * 
		 * <engine startVT="20000" endVT="20000" stepVT="0"> <seed>
		 * <seedValue>023456789</seedValue> <seedValue>023456788</seedValue>
		 * <seedValue>023456787</seedValue> <seedValue>023456786</seedValue>
		 * <seedValue>023456785</seedValue> </seed> </engine>
		 * 
		 */
		xmlString = xmlString + "\n" + "<engine>";
		xmlString = xmlString + "\n\t" + "<seed>";
		for (int index = 0; index < this.engineParameterList.size(); index++) {
			app.add(this.engineParameterList.get(index));
			EngineParameter engineParameter = this.engineParameterList
					.get(index);
			xmlString = xmlString + "\n\t\t" + "<seedValue>"
					+ engineParameter.getSeedValue() + "</seedValue>";
		}
		xmlString = xmlString + "\n\t" + "</seed>";
		xmlString = xmlString + "\n" + "</engine>" + "\n\n";

		/*
		 * 
		 * <!-- Analysis of results --> <resultVT
		 * outputLogFile="logger.dat"/> <resultXYFile fileName="prova"
		 * axisX="VT" axisY="Continuity Index" /> </simulation>
		 */

		xmlString = xmlString + "<resultVT outputLogFile=\"./temp/logger\"/>"
				+ "\n\n";

		// Insert GnuPlot data files
		for (int index = 0; index < this.gnuPlotFileList.size(); index++) {
			GnuPlotFileElement gnuElem = this.gnuPlotFileList.get(index);
			xmlString = xmlString + "<resultXYFile fileName=\""
					+ gnuElem.getFileName() + "\" axisX=\""
					+ gnuElem.getXLabel() + "\" axisY=\"" + gnuElem.getYLabel()
					+ "\" />\n";
		}

		// xmlString = xmlString +
		// "<resultXYFile fileName=\"prova\" axisX=\"VT\" axisY=\"Continuity Index\" />\n";
		// xmlString = xmlString +
		// "<resultXYFile fileName=\"prova\" axisX=\"VT\" axisY=\"Duplicate %\" />\n";

		xmlString = xmlString + "\n" + "</simulation>\n";

		simulations.add(i, app);

		return xmlString;
	}

	/**
	 * Add new NodeParameter to the table
	 * 
	 * @param nodeParameter
	 */
	public void addNodeParameter(NodeParameter nodeParameter) {
		nodeParameterList.add(nodeParameter);
	}

	/**
	 * Add new NodeResource to the table
	 * 
	 * @param nodeResource
	 */
	public void addNodeResource(NodeResource nodeResource) {
		nodeResourceList.add(nodeResource);
	}

	/**
	 * Add new ProcessParameter to the table
	 * 
	 * @param processParameter
	 */
	public void addProcessParameter(ProcessParameter processParameter) {
		processParameterList.add(processParameter);

	}

	/**
	 * Add new EngineParameter to the table
	 * 
	 * @param engineParameter
	 */
	public void addEngineParameter(EngineParameter engineParameter) {
		engineParameterList.add(engineParameter);
	}

	/**
	 * Add a GnuPlotFileElement to the table
	 * 
	 * @param gnuPlotFileElement
	 */
	public void addGnuPlotFileElement(GnuPlotFileElement gnuPlotFileElement) {
		gnuPlotFileList.add(gnuPlotFileElement);
	}

	/**
	 * Remove all elements in the Panel and in the tables
	 */
	public void clearAllData() {
		this.gnuPlotFileList.clear();
		this.nodeParameterList.clear();
		this.processParameterList.clear();
		this.engineParameterList.clear();
	}

}
